﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Data;

namespace RealEstateAgencyDAL
{
    public static class RealEstateDAL
    {
        private static void SaveContext(RealEstateAgencyDatabaseEntities context)
        {
            try
            {
                context.SaveChanges();
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.ToString());
            }
        }

        #region Towns

        public static Town GetTownByID(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Town town = context.Towns.Include("Locations").FirstOrDefault(t => t.TownID == id);

                return town;
            }
        }

        public static void DeleteTown(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Town townToDelete = GetTownByID(id);

                if (townToDelete != null)
                {
                    context.Attach(townToDelete);
                    context.Towns.DeleteObject(townToDelete);
                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("Town not found if:{0}}", id));
                }
            }
        }

        public static void AddTown(Town town)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.Towns.AddObject(town);

                SaveContext(context);
            }
        }

        public static IEnumerable<Town> GetAllTowns()
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                var towns = context.Towns.Include("Locations.Town").Include("Locations.District").ToList();

                return towns;
            }
        }

        public static void EditTown(int id, Town newTown)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Town town = GetTownByID(id);
                
                if (town != null)
                {
                    context.Attach(town);
                    town.TownName = newTown.TownName;

                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("Town not found if:{0}}", id));
                }
            }
        }

        #endregion

        #region Districts

        public static District GetDistrictByID(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                District district = context.Districts.FirstOrDefault(t => t.DistrictID == id);

                return district;
            }
        }

        public static void DeleteDistrict(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                District districtToDelete = GetDistrictByID(id);

                if (districtToDelete != null)
                {
                    context.Attach(districtToDelete);
                    context.Districts.DeleteObject(districtToDelete);
                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("District not found if:{0}}", id));
                }
            }
        }

        public static void AddDistrict(District district)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.Districts.AddObject(district);

                SaveContext(context);
            }
        }

        public static IEnumerable<District> GetAllDistricts()
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                var districts = context.Districts.ToList();

                return districts;
            }
        }

        public static void EditDistrict(int id, District newDistrict)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.Attach(newDistrict);
                context.ObjectStateManager.ChangeObjectState(newDistrict, EntityState.Modified);
                SaveContext(context);
            }
        }
        #endregion

        #region OfferTypes

        public static OfferType GetOfferTypeByID(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                OfferType offerType = context.OfferTypes.FirstOrDefault(t => t.OfferTypeID == id);

                return offerType;
            }
        }

        public static void DeleteOfferType(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                OfferType offerTypeToDelete = GetOfferTypeByID(id);

                if (offerTypeToDelete != null)
                {
                    context.Attach(offerTypeToDelete);
                    context.OfferTypes.DeleteObject(offerTypeToDelete);
                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("OfferType not found if:{0}}", id));
                }
            }
        }

        public static void AddOfferType(OfferType offerType)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.OfferTypes.AddObject(offerType);

                SaveContext(context);
            }
        }

        public static IEnumerable<OfferType> GetAllOfferTypes()
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                var offerTypes = context.OfferTypes.ToList();

                return offerTypes;
            }
        }

        public static void EditOfferType(int id, OfferType newOfferType)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                OfferType offerType = GetOfferTypeByID(id);

                if (offerType != null)
                {
                    context.Attach(offerType);
                    offerType.OfferTypeName = newOfferType.OfferTypeName;

                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("OfferType not found if:{0}}", id));
                }
            }
        }

        #endregion

        #region EstateTypes

        public static EstateType GetEstateTypeByID(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                EstateType estateType = context.EstateTypes.FirstOrDefault(t => t.EstateTypeID == id);

                return estateType;
            }
        }

        public static void DeleteEstateType(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                EstateType estateTypeToDelete = GetEstateTypeByID(id);

                if (estateTypeToDelete != null)
                {
                    context.Attach(estateTypeToDelete);
                    context.EstateTypes.DeleteObject(estateTypeToDelete);
                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("EstateType not found if:{0}}", id));
                }
            }
        }

        public static void AddEstateType(EstateType estateType)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.EstateTypes.AddObject(estateType);

                SaveContext(context);
            }
        }

        public static IEnumerable<EstateType> GetAllEstateTypes()
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                var estateType = context.EstateTypes.ToList();

                return estateType;
            }
        }

        public static void EditEstateType(int id, EstateType newEstateType)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                EstateType estateType = GetEstateTypeByID(id);

                if (estateType != null)
                {
                    context.Attach(estateType);
                    estateType.EstateTypeName = newEstateType.EstateTypeName;

                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("EstateType not found if:{0}}", id));
                }
            }
        }

        #endregion

        #region Extras

        public static Extra GetExtraByID(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Extra extra = context.Extras.FirstOrDefault(t => t.ExtraID == id);

                return extra;
            }
        }

        public static void DeleteExtra(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Extra extraToDelete = GetExtraByID(id);

                if (extraToDelete != null)
                {
                    context.Attach(extraToDelete);
                    context.Extras.DeleteObject(extraToDelete);
                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("Extra not found if:{0}}", id));
                }
            }
        }

        public static void AddExtra(Extra extra)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.Extras.AddObject(extra);

                SaveContext(context);
            }
        }

        public static IEnumerable<Extra> GetAllExtras()
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                var extras = context.Extras.ToList();

                return extras;
            }
        }

        public static void EditExtra(int id, Extra newExtra)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Extra extra = GetExtraByID(id);

                if (extra != null)
                {
                    context.Attach(extra);
                    extra.ExtraName = newExtra.ExtraName;

                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("Extra not found if:{0}}", id));
                }
            }
        }

        #endregion

        #region Pictures

        public static Picture GetPictureByID(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Picture picture = context.Pictures.FirstOrDefault(t => t.PictureID == id);

                return picture;
            }
        }

        public static void DeletePicture(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Picture pictureToDelete = GetPictureByID(id);

                if (pictureToDelete != null)
                {
                    context.Attach(pictureToDelete);
                    context.Pictures.DeleteObject(pictureToDelete);
                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("Picture not found id:{0}}", id));
                }
            }
        }

        public static void AddPicture(Picture picture)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.Pictures.AddObject(picture);

                SaveContext(context);
            }
        }

        public static IEnumerable<Picture> GetAllPictures()
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                var pictures = context.Pictures.ToList();

                return pictures;
            }
        }

        public static void EditPicture(int id, Picture newPicture)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Picture picture = GetPictureByID(id);

                if (picture != null)
                {
                    context.Attach(picture);
                    picture.PictureData = newPicture.PictureData;
                    picture.OfferID = newPicture.OfferID;

                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("Picture not found id:{0}}", id));
                }
            }
        }

        #endregion

        #region Offers

        public static Offer GetOfferByID(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Offer offer = context.Offers
                                     .Include("EstateType")
                                     .Include("OfferType")
                                     .Include("Location.District")
                                     .Include("Location.Town")
                                     .Include("Pictures")
                                     .Include("Picture")
                                     .Include("Extras")
                                     .FirstOrDefault(t => t.OfferID == id);

                return offer;
            }
        }

        public static void DeleteOffer(int id)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                Offer offer = GetOfferByID(id);

                if (offer != null)
                {
                    context.Attach(offer);
                    offer.Active = false;
                    SaveContext(context);
                }
                else
                {
                    throw new ArgumentException(String.Format("Offer not found id:{0}}", id));
                }
            }
        }

        public static IEnumerable<Offer> GetAllOffers()
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                var offers = context.Offers
                                    .Include("EstateType")
                                    .Include("OfferType")
                                    .Include("Location.District")
                                    .Include("Location.Town")
                                    .Include("Pictures")
                                    .Include("Picture")
                                    .Include("Extras")
                                    .ToList();

                return offers;
            }
        }

        public static void EditOffer(Offer offerToEdit)
        {
            using (var context = new RealEstateAgencyDatabaseEntities())
            {
                context.Attach(offerToEdit);
                context.ObjectStateManager.ChangeObjectState(offerToEdit, System.Data.EntityState.Modified);
                SaveContext(context);
            }
        }

        #endregion
    }
}